package com.yorick.authority.util;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yorick.authority.entitys.Node;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * @program: TreeRecursion
 * @description: 模拟树状图以及递归排序
 * @author: Yorick
 * @create: 16/5/2022
**/
@Component
public abstract class TreeRecursion {
    /**
     * 递归处理父级ID，解决多个父级ID问题
     *
     * @param nodes
     * @return
     */

    public List<JSONObject> getNodeJson(Map<Integer, Node> nodes) {
        List<JSONObject> result = new ArrayList<>();
        List<Integer> parentIds = getParentIds(nodes);
        for(Integer parentId : parentIds){
            result.addAll(getNodeJson(parentId, nodes));
        }
        return result;
    }

    /**
     * 递归处理   数据库树结构数据->树形json
     *
     * @param nodeId
     * @param nodes
     * @return
     */
    public List<JSONObject> getNodeJson(int nodeId, Map<Integer, Node> nodes) {
        //当前层级当前node对象
        Node cur = nodes.get(nodeId);
        //当前层级当前点下的所有子节点（实战中不要慢慢去查,一次加载到集合然后慢慢处理）
        List<Node> childList = getChildNodes(nodeId, nodes);

        List<JSONObject> childTree = new ArrayList<>();
        for (Node node : childList) {
            JSONObject o = this.customizeNode(node);
            List<JSONObject> childs = getNodeJson(node.getId(), nodes);  //递归调用该方法
            if (!childs.isEmpty()) {
                o.put("children", childs);
            }
            childTree.add(o);
        }
        return childTree;
    }

    /**
     * 获取当前节点的所有子节点
     *
     * @param nodeId
     * @param nodes
     * @return
     */
    public static List<Node> getChildNodes(int nodeId, Map<Integer, Node> nodes) {
        List<Node> list = new ArrayList<>();
        for (int key : nodes.keySet()) {
            if (nodes.get(key).getParentId() == nodeId) {
                list.add(nodes.get(key));
            }
        }
        return list;
    }

    private static List<Integer> getParentIds(Map<Integer, Node> nodes) {
        List<Integer> result = new ArrayList();
        for (Map.Entry<Integer, Node> entry : nodes.entrySet()) {
            if(nodes.get(entry.getValue().getParentId())==null){
                result.add(entry.getValue().getParentId());
            }else{
                Map<Integer, Node> nodes2 = new HashMap<>();
                nodes2.remove(entry.getValue().getId());
                getParentIds(nodes2);
            }
        }
        TreeSet set = new TreeSet(result);
        result.clear();
        result.addAll(set);
        return result;
    }

    protected abstract JSONObject customizeNode(Node node);

    public static List<JSONObject> sortList(List<JSONObject> list) {

        for (JSONObject parent : list) {
            if (Objects.nonNull(parent.get("children"))) {
                List<JSONObject> children = sortList((List<JSONObject>) parent.get("children"));
                parent.put("children", children);
            }
        }
        Collections.sort(list, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                int a = o1.getInteger("orderNum");
                int b = o2.getInteger("orderNum");
                if (a > b) {
                    return 1;
                } else if (a == b) {
                    return 0;
                } else
                    return -1;
            }
        });
        return list;
    }
}
